using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Threading;
using Services;
using SpaceBattle.Logic.SampleLevel;
using Utilities.Menu.UIElements;
using SpaceBattle.Resources;

namespace SpaceBattle.Menu
{

  using Game = Microsoft.Xna.Framework.Game;

  public class DefeatScreen : Microsoft.Xna.Framework.DrawableGameComponent
  {
    SpriteBatch sprite_batch;
    Matrix screen_transform;
    Texture2D bg, box_body, bwd;
    SpriteFont title_font, text_font, menu_font;
    Button back_to_menu, save_scores, confirm_save;
    SoundEffect click;
    GameMode game_mode;

    VirtualKeyboard keyboard;
    TextEdit text_edit;

    BaseLevelStats user_data;

    bool initialized = false, increase_a = false, save_state = false;
    float alpha = 0.0f, wait_to_tap = 0.5f;
    //private Texture2D up_l_box;
    //private Texture2D lo_l_box;
    //private Texture2D up_r_box;
    //private Texture2D lo_r_box;

    public DefeatScreen(Game game, GameMode game_mode, BaseLevelStats user_data)
      : base(game)
    {
      game.Components.Add(new InputManager(game));

      this.user_data = user_data;
      this.game_mode = game_mode;
    }

    ContentManager Content { get { return Game.Content; } }
    public override void Initialize()
    {
      var input_service = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
      input_service.OnTap += new InputManager.Tap(on_tap);

      user_data.TotalScore += user_data.LevelScore;
      
      base.Initialize();
    }

    protected override void LoadContent()
    {
        sprite_batch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
        screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / SpaceBattleGame.DEFAULT_SCR_WIDTH, GraphicsDevice.Viewport.Height / SpaceBattleGame.DEFAULT_SCR_HEIGHT, 1.0f);
        bg = Content.Load<Texture2D>("LevelFinished/defeat_bg_png");
        bwd = Content.Load<Texture2D>("Menu/button_rwd");
        title_font = Content.Load<SpriteFont>("Fonts/OCRAExtended32");
        text_font = Content.Load<SpriteFont>("Fonts/OCRAExtended18");
        menu_font = Content.Load<SpriteFont>("Fonts/OCRAExtended24");
        //up_l_box = Content.Load<Texture2D>("LevelFinished/hor_left");
        //lo_l_box = Content.Load<Texture2D>("LevelFinished/ver_left");
        //up_r_box = Content.Load<Texture2D>("LevelFinished/hor_right");
        //lo_r_box = Content.Load<Texture2D>("LevelFinished/ver_right");
        box_body = Content.Load<Texture2D>("LevelFinished/victory_bg");
        click = Game.Content.Load<SoundEffect>("Audio/button");

        back_to_menu = new Button { CollisionBox = new Rectangle(10, 
            GraphicsDevice.Viewport.Height / 2 - bwd.Height / 2, bwd.Width, bwd.Height), Label = Strings.Quit, 
            Position = Vector2.Zero };
        var sm = menu_font.MeasureString(Strings.SaveScore); var x = Game.GraphicsDevice.Viewport.Width / 2.0f - sm.X / 2.0f;
        save_scores = new Button { CollisionBox = new Rectangle((int)x - 10, 415, (int)sm.X + 20, (int)sm.Y + 20), 
            Label = Strings.SaveScore, Position = new Vector2(x, 425) };
        sm = menu_font.MeasureString(Strings.Confirm); x = Game.GraphicsDevice.Viewport.Width / 2.0f - sm.X / 2.0f;
        confirm_save = new Button { CollisionBox = new Rectangle((int)x - 10, 415, (int)sm.X + 20, (int)sm.Y + 20), 
            Label = Strings.Confirm, Position = new Vector2(x, 425) };

        text_edit = new TextEdit(text_font, Content.Load<Texture2D>("Menu/text_edit_bg"), 
            new Vector2(GraphicsDevice.Viewport.Width / 2.0f - Content.Load<Texture2D>("Menu/text_edit_bg").Width / 2.0f, 80), 8);
        keyboard = new VirtualKeyboard(text_edit, text_font, Content.Load<SoundEffect>("Audio/keyboard_click"), 
            Content.Load<Texture2D>("Menu/keyboard_bg"), Content.Load<Texture2D>("Menu/key_bg"), 
            Content.Load<Texture2D>("Menu/key_delete"), 200, 150);

        base.LoadContent();
    }

    protected override void Dispose(bool disposing)
    {
        Game.Services.RemoveService(typeof(IInputManager));

        base.Dispose(disposing);
    }

    void on_tap(Vector2 tap_position)
    {
        if (wait_to_tap <= 0.0f)
        {
            var p = tap_position.ToPoint(screen_transform);

            if (save_state && game_mode == GameMode.Survival)
            {
                keyboard.Update(tap_position);

                if (confirm_save.CollisionBox.Contains(p) && text_edit.Text.Length > 1)
                {
                    click.Play(AudioManager.Volume, 0.0f, 0.0f);
                    var n = text_edit.Text.ToString();
                    Leaderboard.AddScore(new LeaderboardEntry()
                    {
                        Score = user_data.TotalScore,
                        Name = n,
                        Date = DateTime.Now.ToString().Split(' ')[0]
                    });
                    StateManager.SelectMenu(Game);
                }
            }

            if (back_to_menu.CollisionBox.Contains(p))
            {
                if (game_mode == GameMode.Campaign)
                {
                    Leaderboard.ResetCampaignState(false);
                }
                StateManager.SelectMenu(Game);
                click.Play(AudioManager.Volume, 0.0f, 0.0f);
            }
            else
                if (save_scores.CollisionBox.Contains(p) && !save_state && !(game_mode == GameMode.Campaign))
                {
                    save_state = true;
                    click.Play(AudioManager.Volume, 0.0f, 0.0f);
                }
        }
    }

    public override void Update(GameTime gameTime)
    {
        float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

        wait_to_tap -= dt;

        if (!initialized)
        {
            alpha = MathHelper.Clamp(alpha + dt * 2.0f, 0.0f, 1.0f);
            if (alpha == 1.0f)
            {
                initialized = true;
            }
        }

        if (save_state)
        {
            if (!increase_a)
            {
                alpha = MathHelper.Clamp(alpha - dt * 2.0f, 0.0f, 1.0f);
                if (alpha == 0.0f)
                    increase_a = true;
            }
            else
                alpha = MathHelper.Clamp(alpha + dt, 0.0f, 1.0f);
        }

        base.Update(gameTime);
    }

    Rectangle box_rect = new Rectangle(35, 150, 410, 335);
    public override void Draw(GameTime gameTime)
    {
      GraphicsDevice.Clear(Color.CornflowerBlue);

      sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

      sprite_batch.Draw(bg, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);

      if (!save_state || !increase_a)
      {
          sprite_batch.Draw(box_body, new Rectangle((int)(GraphicsDevice.Viewport.Width / 2.0f - box_body.Width / 2.0f),
          20, box_body.Width, 380), Color.White * alpha);
          sprite_batch.DrawString(title_font, Strings.Defeat, new Vector2(CenterValue(Game.GraphicsDevice.Viewport.Width, 
              title_font.MeasureString(Strings.Defeat).X), 120), Color.White * alpha);
          sprite_batch.DrawString(text_font, Strings.TotalScore + user_data.TotalScore,
              new Vector2(Game.GraphicsDevice.Viewport.Width / 2.0f -
              text_font.MeasureString(Strings.TotalScore + user_data.TotalScore).X / 2.0f, 260), Color.White * alpha);

          if (game_mode == GameMode.Survival)
          {
              sprite_batch.DrawString(menu_font, save_scores.Label, save_scores.Position + Vector2.One * 2.0f, Color.Black * alpha);
              sprite_batch.DrawString(menu_font, save_scores.Label, save_scores.Position, Color.White * alpha);
          }
      }
      else
      {
          keyboard.DrawKeyboard(gameTime, sprite_batch, alpha);

          sprite_batch.DrawString(menu_font, confirm_save.Label, confirm_save.Position + Vector2.One * 2.0f, Color.Black * (text_edit.Text.Length > 1 ? alpha : Math.Min(0.5f, alpha)));
          sprite_batch.DrawString(menu_font, confirm_save.Label, confirm_save.Position, Color.White * (text_edit.Text.Length > 1 ? alpha : Math.Min(0.5f, alpha)));
      }

      sprite_batch.Draw(bwd, back_to_menu.CollisionBox, Color.White * alpha);

      sprite_batch.End();

      base.Draw(gameTime);
    }

    private float CenterValue(float screen_dim, float item_width)
    {
        return screen_dim / 2.0f - item_width / 2.0f;
    }
  }
}